public class Test {
    /**
     * 由于String的不可更改特性，为了方便字符串的修改，Java中又提供StringBuilder和StringBuffer类。
     * @param args
     */
    //StringBuffer和StringBuilder的都不可以直接赋值
    //必须是用new来赋值
    //StringBuffer和StringBuilder两者大部分功能相同
    //但是细节的功能有些不同
    public static void main1(String[] args) {//append添加
        StringBuilder stringBuilder = new StringBuilder("abcd");
        //StringBuilder中有许多构造方法，有无参的和各种类型的参数
        //StringBuilder也进行了重写了toString
        System.out.println(stringBuilder);
    }

    //append方法
    public static void main2(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("abcd");
        System.out.println(stringBuilder);
        stringBuilder.append(1);
        stringBuilder.append("po");
        stringBuilder.append("abcd").append(12.5);
        System.out.println(stringBuilder);
        //关于string为什么直接进行修改，会效率低下，因为会每次进行返回了一个新的对象
        //不断的返回，会造成系统的缓存的拥堵。
        //stringBuilder是一个直接在一个对象的空间里去进行修改，不会改变这个对象的所处空间的位置，
        //仅仅在这个空间里修改

        //append返回的是当前对象的引用
        //在尾部追加，相当于String的+=，可以追加：boolean、char、char[]、
        //double、ﬂoat、int、long、Object、String、StringBuﬀ的变量

    }


    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("abcd");
        //setCharAt((int index,char ch)方法
        stringBuilder.setCharAt(0,'b');//将index位置的字符设置为ch
        System.out.println(stringBuilder);
        char ch = stringBuilder.charAt(2);//获取某个位置的字符，同string类
        System.out.println(ch);

        //deleteCharAt(int index)删除index位置的字符
        stringBuilder.deleteCharAt(0);
        System.out.println(stringBuilder);

        //插入：insert():在offset位置插入：八种基类类型 & String类型 & Object类型数据
        stringBuilder.insert(1,"00000000000000000000");
        System.out.println(stringBuilder);

        //删除delete(int start,int end)
        //左闭右开的区间
        stringBuilder.delete(1,21);
        System.out.println(stringBuilder);

        //反转字符串reverse()方法
        stringBuilder.reverse();
        System.out.println(stringBuilder);

        /**
         * 为什么我们不用新的StringBuilder来接收？
         * 因为这些大部分方法的修改都是基于stringBuilder最开始所创建的空间中去修改
         * 所以返回还是这个空间的对象的值，返回的都是stringBuilder的对象
         */

        /*String str = stringBuilder;
        //这种直接赋值给string类型是错误的，无法实现，所以我们要重写toString方法*/

        String str = stringBuilder.toString();//将其转化为string类型需要用toString，从一个字符序列转化为String对象
        System.out.println(str);
    }

    /*

    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }

    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

    我们发现两者的差了一个关键字synchronized
    这个关键字十分重要，我们需要明白了它的意思：同步
    synchronized这个关键字一般用于多线程的情况下，我们可以认为他其实相当于一把锁
    简单的说：就是有许多变量去调用这个append方法，但是当我们传进去一个变量，内部进行锁上，这个方法与外界无法有联系
    等到作用完之后才能解开，再次往里存入新的变量，也会发生这种情况

    所以频繁的加锁与释放锁，势必会有效率的问题
    一般在单线程的情况下我们用stringBuilder
    一般在多线程的情况下我们用stringBuffer
    两者内部的方法基本就是一致的
    */

    //注意：String和StringBuilder类不能直接转换。如果要想互相转换，可以采用如下原则:
    //String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
    //StringBuilder变为String: 调用toString()方法。


    /**
     *String的内容无法修改，而StringBuilder和StringBuffer的内容可以修改
     */
}
